const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const tsImportPluginFactory = require('ts-import-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const theme = require('./theme');
const appConfig = require('./appConf');

const config = {
    // 运行模式
    env: process.env.NODE_ENV || 'development',
    // 项目结构
    pathBase: path.resolve(__dirname, '..'),
    dirClientSrc: 'src',
    dirDist: 'dist',
    // 脚手架设置
    // app 相对网站根目录路径
    virtualPath: '/'
}

// 构建全局参数
config.globals = Object.assign({}, {
    __VIRTUALPATH__: JSON.stringify(config.virtualPath),
    'process.env': { NODE_ENV: JSON.stringify(config.env) },
    NODE_ENV: config.env,
    __DEV__: config.env === 'development',
    __PROD__: config.env === 'production',
    __BASENAME__: JSON.stringify(process.env.BASENAME || '')
}, appConfig);

// 构建常用路径
config.paths = {
    base: config.pathBase,
    clientSrc: path.resolve(config.pathBase, config.dirClientSrc),
    dist: path.resolve(config.pathBase, config.dirDist)
}

// resolve extensions
config.resolveExtensions = ['.ts', '.tsx', '.js', '.json'];

// module no parse
config.moduleNoParse = [];
config.moduleNoParse.push(/moment-with-locales/);

// modules
config.moduleRules = [];
config.moduleRules.push({
    test: /\.tsx?$/,
    loader: 'ts-loader',
    options: {
        transpileOnly: true,
        getCustomTransformers: () => ({
            before: [tsImportPluginFactory([
                {
                    libraryName: 'antd',
                    libraryDirectory: 'es',
                    style: true
                },
                {
                    style: false,
                    libraryName: 'lodash',
                    libraryDirectory: null,
                    camel2DashComponentName: false
                }
            ])]
        }),
        compilerOptions: {
            module: 'es2015'
        }
    },
    exclude: /node_modules/
});
// css-loader
config.moduleRules.push({
    test: /\.css$/,
    use: [
        { loader: 'style-loader' },
        {
            loader: 'postcss-loader',
            options: { plugins: () => [config.cssAutoprefixerPlugin] }
        }
    ]
});
// scss-loader
config.moduleRules.push({
    test: /\.scss$/,
    use: [
        { loader: 'style-loader' },
        {
            loader: 'postcss-loader',
            options: { plugins: () => [config.cssAutoprefixerPlugin] }
        },
        { loader: 'sass-loader' }
    ]
});

// less-loader
config.moduleRules.push({
    test: /\.less$/,
    use: [
        { loader: 'style-loader' },
        {
            loader: 'postcss-loader',
            options: { plugins: () => [config.cssAutoprefixerPlugin] }
        },
        {
            loader: 'less-loader',
            options: {
                modifyVars: theme
            }
        }
    ]
});
// images loaders
config.moduleRules.push({
    test: /\.(png|jpe?g|gif)(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: 8192,
                name: '[name].[ext]'
            }
        }
    ]
});
config.moduleRules.push({
    test: /\.svg(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: 8192,
                name: '[name].[ext]',
                mimetype: 'image/svg+xml'
            }
        }
    ]
});
config.moduleRules.push({
    test: /\.woff(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: 8192,
                name: '[name].[ext]',
                mimetype: 'application/font-woff'
            }
        }
    ]
});
config.moduleRules.push({
    test: /\.woff2(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: 8192,
                name: '[name].[ext]',
                mimetype: 'application/font-woff2'
            }
        }
    ]
});
config.moduleRules.push({
    test: /\.ttf(\?.*)?$/,
    use: [
        {
            loader: 'url-loader',
            options: {
                limit: 8192,
                name: '[name].[ext]',
                mimetype: 'application/octet-stream'
            }
        }
    ]
});
config.moduleRules.push({
    test: /\.otf(\?.*)?$/,
    use: [
        {
            loader: 'file-loader',
            options: {
                limit: 8192,
                name: '[name].[ext]'
            }
        }
    ]
});

// __DEV__
if (config.globals.__DEV__) {
    config.moduleRules.push({ enforce: 'pre', test: /\.js$/, loader: 'source-map-loader' });
}

// 提取 vendor 到 vendor.js 设置
// 如果不需要支持IE 请移除 babel-polyfill
config.compilerVendors = [
    'babel-polyfill',
    'react',
    'react-redux',
    'react-router',
    'react-router-dom',
    'react-router-redux',
    'redux'
]

const pkg = require('../package.json');

config.compilerVendors = config.compilerVendors.filter(dep => {
    if (pkg.dependencies[dep]) {
        return true
    }

    debug(
        `Package "${dep}" was not found as an npm dependency in package.json; ` +
        `it won't be included in the webpack vendor bundle.
Consider removing it from \`compiler_vendors\` in ~/config/index.js`
    )
})

// HtmlWebpackConfig
config.htmlWebpackBaseConfig = {
    title: '',
    filename: 'index.html',
    template: path.resolve(config.paths.clientSrc, './static/index.ejs'),
    favicon: path.resolve(config.paths.clientSrc, './static/favicon.ico'),
    inject: 'body',
    hash: false,
    showErrors: false,
    minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
    }
}

// css auto prefix
config.cssAutoprefixerPlugin = autoprefixer({
    browsers: [
        'iOS >= 7', 'Android >= 4.1',
        'last 10 Chrome versions', 'last 10 Firefox versions',
        'Safari >= 6', 'ie > 8']
});

// optimization
config.optimization = () => {
    const optimization = {};

    optimization.splitChunks = {
        cacheGroups: {
            priority: '0',
            vendor: {
                chunks: 'async',
                name: 'vendor',
                minSize: 0,
                minChunks: 2
            }
        }
    }
};

// performance
config.performance = {
    hints: config.globals.__PROD__ ? 'error' : false,
    maxAssetSize: 4 * 1024 * 1024,
    maxEntrypointSize: 4 * 1024 * 1024
};

// plugins
config.plugins = (global, htmlWebpackConfig) => {
    const plugins = [];

    plugins.push(new ForkTsCheckerWebpackPlugin());

    if (config.globals.__PROD__) {
        plugins.push(new webpack.optimize.OccurrenceOrderPlugin());
    }

    plugins.push(new webpack.DefinePlugin(global));
    plugins.push(new HtmlWebpackPlugin(htmlWebpackConfig));
    plugins.push(new CopyWebpackPlugin([
        { from: 'src/static/nprogress.js', to: 'nprogress.js' },
        { from: 'src/static/nprogress.css', to: 'nprogress.css' },
        { from: 'config/antd/localfont/iconfont.eot', to: 'antd_iconfont.eot' },
        { from: 'config/antd/localfont/iconfont.svg', to: 'antd_iconfont.svg' },
        { from: 'config/antd/localfont/iconfont.ttf', to: 'antd_iconfont.ttf' },
        { from: 'config/antd/localfont/iconfont.woff', to: 'antd_iconfont.woff' }
    ]));

    plugins.push(new webpack.ContextReplacementPlugin(
        /moment[\/\\]locale$/, /zh-cn/
    ));

    return plugins;
}

module.exports = config
